package cn.com.dcsgo.library.client.service.impl;

import cn.com.dcsgo.library.client.domain.dto.PageDTO;
import cn.com.dcsgo.library.client.domain.po.Book;
import cn.com.dcsgo.library.client.domain.po.BookCopies;
import cn.com.dcsgo.library.client.domain.po.BorrowRecord;
import cn.com.dcsgo.library.client.domain.query.BookPageQuery;
import cn.com.dcsgo.library.client.domain.vo.BookCopiesVO;
import cn.com.dcsgo.library.client.domain.vo.BookOverviewVO;
import cn.com.dcsgo.library.client.domain.vo.BookVO;
import cn.com.dcsgo.library.client.enums.BookStatus;
import cn.com.dcsgo.library.client.mapper.BooksMapper;
import cn.com.dcsgo.library.client.service.IBooksService;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Dcsgo
 * @since 2024-09-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BooksServiceImpl extends ServiceImpl<BooksMapper, Book> implements IBooksService {
    /**
     * 通过图书id获取图书复本id集合
     *
     * @param bookId 图书id
     * @return 复本id集合
     */
    @Override
    public List<Long> queryCopiesIdsById(Long bookId) {
        List<BookCopies> bookCopies = Db.lambdaQuery(BookCopies.class)
                .select(BookCopies::getId)
                .eq(BookCopies::getBookId, bookId)
                .list();
        return new ArrayList<>(bookCopies.stream().map(BookCopies::getId).toList());
    }

    @Override
    public List<BookCopiesVO> queryCopiesDetails(Long bookId) {
        List<Long> copiesIds = queryCopiesIdsById(bookId);
        if (copiesIds.isEmpty()) {
            return Collections.emptyList();
        }
        List<BorrowRecord> borrowRecords = Db.lambdaQuery(BorrowRecord.class)
                .select(BorrowRecord::getBookCopiesId, BorrowRecord::getStatus)
                .in(BorrowRecord::getBookCopiesId, copiesIds)
                .eq(BorrowRecord::getStatus, BookStatus.BORROWING)
                .list();
        //复本没有借阅记录
        if (borrowRecords.isEmpty()) {
            return BookCopiesVO.ofCopiesIds(copiesIds);
        }
        List<BookCopiesVO> bookCopiesVOS = BookCopiesVO.ofBorrowRecords(borrowRecords);
        List<Long> borrowCopiesIds = borrowRecords.stream().map(BorrowRecord::getBookCopiesId).toList();
        copiesIds.removeAll(borrowCopiesIds);
        bookCopiesVOS.addAll(BookCopiesVO.ofCopiesIds(copiesIds));
        return bookCopiesVOS;
    }

    @Override
    public PageDTO<BookOverviewVO> queryBookByPage(BookPageQuery pageQuery) {
        Integer id = pageQuery.getId();
        String title = pageQuery.getTitle();
        String author = pageQuery.getAuthor();
        String isbn = pageQuery.getIsbn();
        String category = pageQuery.getCategory();
        LocalDate minPublishedDate = pageQuery.getMinPublishedDate();
        LocalDate maxPublishedDateBegin = pageQuery.getMaxPublishedDate();
        Page<Book> page = pageQuery.toMpPageDefaultOrderByUpdateTime();
        lambdaQuery()
                .like(title != null, Book::getTitle, title)
                .like(author != null, Book::getAuthor, author)
                .like(category != null, Book::getCategory, category)
                .eq(id != null, Book::getId, id)
                .eq(isbn != null, Book::getIsbn, isbn)
                .ge(minPublishedDate != null, Book::getPublishedDate, minPublishedDate)
                .le(maxPublishedDateBegin != null, Book::getPublishedDate, maxPublishedDateBegin)
                .page(page);
        return PageDTO.of(page, BookOverviewVO.class);
    }

    @Override
    public BookVO queryBookDetails(Long bookId) {
        //查出图书信息
        Book book = getById(bookId);
        if (book == null) {
            throw new IllegalArgumentException("不存在该图书");
        }
        //查出复本信息
        BookVO bookVO = BeanUtil.copyProperties(book, BookVO.class);
        bookVO.setCopies(queryCopiesDetails(bookId));
        return bookVO;
    }
}